package top.jacktgq.sxt.bio.ChatRoom.version6;

import top.jacktgq.sxt.bio.ChatRoom.version6.utils.ResourceUtils;

import java.io.*;
import java.net.Socket;

/**
 * @Author CandyWall
 * @Date 2019/10/22--18:44
 * @Description  在线聊天室：客户端
 *               目标：加入容器实现群聊
 */
public class Client {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("请输入用户名：");
        String username = reader.readLine();
        System.out.println("客户端启动...");
        //1、建立连接：使用Socket创建客户端+服务的端口
        Socket client = new Socket("localhost", 8888);
        //2、客户端发送消息
        new Thread(new Send(client, username)).start();
        //3、获取服务器端发来的消息
        new Thread(new Receive(client)).start();
    }

    /**     *   封装功能：
     *       1、发送消息
     *       2、从控制台获取输入消息
     *       3、释放资源
     *       4、重写了run方法
     */
    static class Send implements Runnable {

        private BufferedReader console;
        private Socket client;
        private DataOutputStream dos;
        private Boolean isRunning;
        public Send(Socket client, String username) {
            this.client = client;
            try {
                console = new BufferedReader(new InputStreamReader(System.in));
                dos = new DataOutputStream(client.getOutputStream());
                //在线程启动之前，先将用户名传过去
                dos.writeUTF(username);
                isRunning = true;
            } catch (IOException e) {
                e.printStackTrace();
                release();
            }
        }

        //从控制台获取消息
        private String getStrFromConsole() {
            String msg = null;
            try {
                msg = console.readLine();
            } catch (IOException e) {
                e.printStackTrace();
                release();
            }
            return msg;
        }

        //释放资源
        private void release() {
            //停止本次与客户端的通信（接收消息和发送消息）
            this.isRunning = false;
            ResourceUtils.close(dos, client);
        }

        @Override
        public void run() {
            while (isRunning) {
                send();
            }
        }

        //发送消息
        private void send() {
            try {
                String msg = getStrFromConsole();
                //过滤掉空字符串
                if (!"".equals(msg)) {
                    dos.writeUTF(msg);
                    dos.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
                release();
            }
        }
    }

    /**
     *  客户端接收消息线程
     *   封装功能：
     *       1、接收消息
     *       2、释放资源
     *       3、重写了run方法
     */
    static class Receive implements Runnable {
        private Socket client;
        private DataInputStream dis;
        private Boolean isRunning;

        public Receive(Socket client) {
            this.client = client;
            try {
                dis = new DataInputStream(client.getInputStream());
                isRunning = true;
            } catch (IOException e) {
                e.printStackTrace();
                release();
            }
        }

        private String receive() {
            String content = null;
            try {
                content = dis.readUTF();
            } catch (IOException e) {
                e.printStackTrace();
                release();
            }
            return content;
        }

        //释放资源
        private void release() {
            //停止本次与客户端的通信（接收消息和发送消息）
            this.isRunning = false;
            ResourceUtils.close(dis, client);
        }

        @Override
        public void run() {
            while (isRunning) {
                String content = receive();
                System.out.println(content);
            }
        }
    }
}
